package com.paul.common.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.paul.common.utils.Sign.MD5SignUtil;
import com.paul.common.utils.Sign.RSASignUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpMethod;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @author ZMK
 * @date 2022/12/19 13:58
 * @description 签名方法
 */
public class PaulSignUtil {
    private static String appSecret = "11111@WDS1";

    public static Boolean verify(HttpServletRequest request) {

        Map<String, String> params = getAllParams(request);
        String sign = params.get("sign");
        String newSign = sign(params);

        switch (params.get("signType")) {
            case "MD5":
                System.out.println("sign:" + sign);
                System.out.println("newSign:" + newSign);
                return sign.equalsIgnoreCase(newSign);
            case "RSA":
            default:
                return false;
        }

    }


    public static String sign(Map<String, String> params) {
        //过滤签名参数
        params = paraFilter(params);
        switch (params.get("signType")) {
            case "MD5":
                return MD5SignUtil.sign(createValueLinkString(params), appSecret, params.get("inputCharset"));
            case "RSA":
                return "";
            default:
                return "";
        }
    }

    public static Map<String, String> getAllParams(HttpServletRequest request) {
        String appId = request.getHeader("appId");
//        String appSecret = request.getHeader("appSecret");
        String timeStamp = request.getHeader("timeStamp");
        String nonceStr = request.getHeader("nonceStr");
        String signType = request.getHeader("signType");
        String version = request.getHeader("version");
        String inputCharset = request.getHeader("inputCharset");

        Map<String, String> params = new HashMap<>();

        if (request.getMethod().equals(HttpMethod.POST.toString())) {
            String requestBody = HttpContextUtil.getRequestBodyToStr(request);
            if (StringUtils.isBlank(requestBody)) {
                return null;
            }
            params = JSON.parseObject(requestBody, new TypeReference<HashMap<String, String>>() {
            });
        }
        if (request.getMethod().equals(HttpMethod.GET.toString())) {
            params = MapUrlParamsUtil.getUrlParams(request.getQueryString());
        }
        params.put("appId", appId);
        params.put("timeStamp", timeStamp);
        params.put("nonceStr", nonceStr);
        params.put("signType", signType);
        params.put("version", version);
        params.put("inputCharset", inputCharset);

        return params;
    }


    /**
     * 参数拦截
     *
     * @param sArray
     * @return
     */
    public static Map<String, String> paraFilter(Map<String, String> sArray) {
        Map<String, String> result = new HashMap<String, String>(sArray.size());
        if (sArray.size() <= 0) {
            return result;
        }
        for (String key : sArray.keySet()) {
            String value = sArray.get(key);
            if (value == null || value.equals("") || key.equalsIgnoreCase("sign")) {
                continue;
            }
            result.put(key, value);
        }
        return result;
    }

    /**
     * 把数组所有元素排序，并按照value拼接成待簽名串(value爲空的域，不參與待簽名串)
     *
     * @param params 需要排序并参与字符拼接的参数组
     * @return 拼接后字符串
     */
    public static String createValueLinkString(Map<String, String> params) {
        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);
        String prestr = "";
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);
            prestr = prestr + value;
        }
        return prestr;
    }

}
